import process from 'process'
import * as step from '@flow-step/step-toolkit'
import sinon from 'sinon';
import {getOssRamCertificate} from '../src/certificate'
import {expect} from 'chai'

describe('getOssRamCertificate', () => {
    let sandbox: sinon.SinonSandbox;
    let processEnv: NodeJS.ProcessEnv;
    let getOssRamStsCertificateStub: sinon.SinonStub;

    before(() => {
        sandbox = sinon.createSandbox();
        processEnv = process.env;
        getOssRamStsCertificateStub = sandbox.stub(step.certificate, 'getOssRamStsCertificate');
    });

    after(() => {
        sandbox.restore();
        process.env = processEnv;
    });

    beforeEach(() => {
        process.env.FLOW_JOB_TOKEN = 'mockFlowJobToken';
        process.env.SERVICE_CONNECTION_ID = 'mockConnectionId';
    });

    it('should return the certificate when all conditions are met', async () => {
        const mockCertificate = {
            accessKeyId: 'mock_ak',
            accessKeySecret: 'mock_sk',
            securityToken: 'mock_sts',
            ossPathPrefix: 'mock_ossPathPerfix',
            bucketName: 'mock_bucket',
        };

        getOssRamStsCertificateStub.resolves(mockCertificate);

        const certificate = await getOssRamCertificate();

        expect(getOssRamStsCertificateStub.calledWith(process.env['FLOW_JOB_TOKEN'],step.certificate.OssBucketType.ASSETS)).to.be.true;
        expect(certificate).to.deep.equal(mockCertificate);
    });

    it('should throw an error if FLOW_JOB_TOKEN is not set', async () => {
        delete process.env.FLOW_JOB_TOKEN;

        try {
            await getOssRamCertificate();
            expect.fail('Expected an error to be thrown');
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.equal('missing FLOW_JOB_TOKEN');
        }
    });

    it('should throw an error if getOssRamStsCertificate returns undefined', async () => {
        getOssRamStsCertificateStub.resolves(undefined);

        try {
            await getOssRamCertificate();
            expect.fail('Expected an error to be thrown');
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.equal('get ossRamStsCertificate but error: undefined');
        }
    });

    it('should throw an error if getOssRamStsCertificate returns a certificate with an empty accessKeyId', async () => {
        const mockCertificate = {
            accessKeyId: '',
            accessKeySecret: 'mock_sk',
            securityToken: 'mock_sts',
            ossPathPrefix: 'mock_ossPathPerfix',
            bucketName: 'mock_bucket',
        };


        getOssRamStsCertificateStub.resolves(mockCertificate);

        try {
            await getOssRamCertificate();
            expect.fail('Expected an error to be thrown');
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.equal('get ossRamStsCertificate but error: {"accessKeyId":"","accessKeySecret":"mock_sk","securityToken":"mock_sts","ossPathPrefix":"mock_ossPathPerfix","bucketName":"mock_bucket"}');
        }
    });
});